<?php

namespace App\Models;

use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

/**
 * 图片直播模型
 * Class ArticleModel
 * @package app\common\model
 */
class PictureLive extends BaseModel
{
    use HasFactory;

    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'change_time';

    protected $table = 'picture_live';

    /**
     * 更新浏览量
     *
     * @param act_id 活动id
     * @param number 多少次更新一次
     * @param second 大于秒更新一次（取决于后一次请求事件）
     */
    public function updateBrowseNumber($act_id, $number = 100, $second = 300)
    {
        if ($number == 1) {
            return $this->where('act_id', $act_id)->increment('browse_num', 1);
        }

        $key = $act_id . 'picture_live_browse_number';
        $res = Cache::pull($key); //从缓存中获取缓存项然后删除，使用 pull 方法，如果缓存项不存在的话返回 null
        $data = [];
        if (empty($res)) {
            $data['number'] = 1;
            $data['create_time'] = time();
            Cache::put($key, $data, 3600 * 24);
        } else {
            //数据大于50或者时间超过5分钟，则更新一次数据
            if ($res['number'] >= $number || time() - $res['create_time'] >= $second) {
                return $this->where('id', $act_id)->increment('browse_num', $res['number'] + 1);
            } else {
                $data['number'] = $res['number'] + 1;
                $data['create_time'] = $res['create_time'];
                Cache::put($key, $data, 3600 * 24);
            }
        }
        return true;
    }

    /**
     * 列表
     * @param limit int 分页大小
     * @param is_play string 是否发布   1 已发布  2 未发布
     * @param keywords string 搜索关键词
     * @param start_time datetime 活动开始时间    数据格式  年月日
     * @param end_time datetime 活动结束时间
     * @param create_start_time datetime 活动创建开始时间   数据格式 年月日时分秒
     * @param create_end_time datetime 活动创建结束时间
     */
    public function lists($field, $keywords, $is_play, $start_time, $end_time, $create_start_time, $create_end_time, $limit = 10)
    {
        if (empty($field)) {
            $field = [
                'id',
                'title',
                'img',
                'host_handle',
                'tel',
                'con_start_time',
                'con_end_time',
                'vote_start_time',
                'vote_end_time',
                'browse_num',
                'address',
                'vote_way',
                'number',
                'uploads_number',
                'uploads_way',
                'intro',
                'is_appoint',
                'is_check',
                'is_play',
                'qr_url',
                'create_time'
            ];
        }
        $res = $this->select($field)
            ->where(function ($query) use ($keywords) {
                if ($keywords) {
                    $query->where('title', 'like', "%$keywords%");
                }
            })->where(function ($query) use ($is_play, $start_time, $end_time, $create_start_time, $create_end_time) {
                if ($is_play) {
                    $query->where('is_play', $is_play);
                }
                if ($start_time && $end_time) {
                    $query->whereBetween('con_start_time', [$start_time, $end_time]);
                }
                if ($create_start_time && $create_end_time) {
                    $query->whereBetween('create_time', [$create_start_time, $create_end_time]);
                }
            })
            ->where('is_del', 1)
            ->orderByDesc('con_end_time')
            ->paginate($limit)
            ->toArray();

        $controllerObj = new Controller();
        $res = $controllerObj->disPageData($res);
        return $res;
    }

    /**
     * 列表(图片直播和视频直播数据合并)
     * @param limit int 分页大小
     * @param is_play string 是否发布   1 已发布  2 未发布
     * @param keywords string 搜索关键词
     * @param start_time datetime 活动开始时间    数据格式  年月日
     * @param end_time datetime 活动结束时间
     * @param create_start_time datetime 活动创建开始时间   数据格式 年月日时分秒
     * @param create_end_time datetime 活动创建结束时间
     */
    public function liveLists($keywords, $is_play, $start_time, $end_time, $create_start_time, $create_end_time, $limit = 10)
    {
        $field1 = [
            'id',
            'title',
            'img',
            'host_handle',
            'tel',
            'con_start_time as start_time',
            'con_end_time as end_time',
            'browse_num',
            'address',
            'intro',
            'create_time',
            DB::raw('1 as status'),
            DB::raw('1 as node') //保证列数相同但是同时用
        ];
        $field2 = [
            'id',
            'title',
            'img',
            'host_handle',
            'tel',
            'start_time',
            'end_time',
            'browse_num',
            'address',
            'intro',
            'create_time',
            'status',
            DB::raw('2 as node')
        ];
        $picture_res = $this->select($field1)
            ->where(function ($query) use ($keywords) {
                if ($keywords) {
                    $query->where('title', 'like', "%$keywords%");
                }
            })->where(function ($query) use ($is_play, $start_time, $end_time, $create_start_time, $create_end_time) {
                if ($is_play) {
                    $query->where('is_play', $is_play);
                }
                if ($start_time && $end_time) {
                    $query->whereBetween('con_start_time', [$start_time, $end_time]);
                }
                if ($create_start_time && $create_end_time) {
                    $query->whereBetween('create_time', [$create_start_time, $create_end_time]);
                }
            })
            ->where('is_del', 1)
            ->orderByDesc('id');


        $videoLiveModel = new VideoLive();
        $res = $videoLiveModel->select($field2)
            ->where(function ($query) use ($keywords) {
                if ($keywords) {
                    $query->where('title', 'like', "%$keywords%");
                }
            })->where(function ($query) use ($is_play, $start_time, $end_time, $create_start_time, $create_end_time) {
                if ($is_play) {
                    $query->where('is_play', $is_play);
                }
                if ($start_time && $end_time) {
                    $query->whereBetween('con_start_time', [$start_time, $end_time]);
                }
                if ($create_start_time && $create_end_time) {
                    $query->whereBetween('create_time', [$create_start_time, $create_end_time]);
                }
            })
            ->where('is_del', 1);
        //联合后，才排序
        $res = $picture_res
            ->union($res)
            ->orderByDesc('start_time')
            ->paginate($limit)
            ->toArray();
        $controllerObj = new Controller();
        $res = $controllerObj->disPageData($res);
        return $res;
    }


    /**
     * 详情
     * @param id int 直播id 或 二维码 token值
     * @param is_play int 是否发布状态
     * @param user_id int 用户id，用于查询我自己的图片详情
     */
    public function detail($id, $is_play = null, $field = null, $user_id = null)
    {
        if (empty($field)) {
            $field = [
                'id',
                'title',
                'main_img',
                'img',
                'host_handle',
                'tel',
                'con_start_time',
                'con_end_time',
                'vote_start_time',
                'vote_end_time',
                'address',
                'vote_way',
                'number',
                'uploads_number',
                'uploads_way',
                'intro',
                'is_check',
                'is_play',
                'is_appoint',
                'create_time',
                'watermark_img',
                'watermark_type',
                'watermark_text',
                'share_title',
                'share_img',
                'theme_color',
                'animation',
                'animation_time'
            ];
        }
        $res = $this->select($field)
            ->where(function ($query) use ($id, $is_play, $user_id) {
                if ($is_play) {
                    $query->where('is_play', $is_play);
                }
                if ($user_id) {
                    $query->where('user_id', $user_id);
                }
                if (is_numeric($id)) {
                    $query->where('id', $id);
                } else {
                    $query->where('qr_code', $id);
                }
            })
            ->where('is_del', 1)
            ->first();

        return $res;
    }

    /**
     * 我的图片直播活动列表
     * @param user_id int 用户tid
     * @param limit int 分页大小
     */
    public function myPictureLiveLists($user_id, $limit = 10)
    {
        $pictureLiveWorksModel = new PictureLiveWorks();
        //我的活动数据
        $act_id_all = $pictureLiveWorksModel->where('user_id', $user_id)->groupBy('act_id')->where('way', 1)->pluck('act_id')->toArray(); //先只允许看前台上传的
        if (empty($act_id_all)) {
            return [];
        }
        $act_list = $this->select('id', 'title')->where('is_del', 1)->where('is_play', 1)->whereIn('id', $act_id_all)->orderByDesc('id')->paginate($limit)->toArray();
        if (empty($act_list['data'])) {
            return [];
        }
        $field = ['id', 'act_id', 'user_id', 'title', 'cover', 'thumb_img', 'width', 'height', 'size', 'ratio', 'browse_num', 'vote_num', 'status', 'create_time'];
        foreach ($act_list['data'] as $key => $val) {
            //获取作品列表
            $works_list = $pictureLiveWorksModel->select($field)->where('user_id', $user_id)->where('act_id', $val['id'])->whereIn('status', [1, 2, 3, 4])->where('is_del', 1)->orderByDesc('id')->limit(9)->get()->toArray();
            $count = $pictureLiveWorksModel->select($field)->where('user_id', $user_id)->where('act_id', $val['id'])->whereIn('status', [1, 2, 3, 4])->where('is_del', 1)->count();
            $act_list['data'][$key]['works_list'] = $works_list;
            $act_list['data'][$key]['count'] = $count; //返回总数
        }
        return $act_list;
    }

    /**
     * 我的点赞过的图片直播活动列表
     * @param user_id int 用户tid
     * @param limit int 分页大小
     */
    public function myVotePictureLiveLists($user_id, $limit = 10)
    {
        $pictureLiveVoteModel = new PictureLiveVote();
        //我的活动数据
        $act_id_all = $pictureLiveVoteModel->from($pictureLiveVoteModel->getTable() . ' as v')
            ->join('picture_live_works as w', 'w.id', '=', 'v.works_id')
            ->where('w.is_del', 1)
            ->where('v.user_id', $user_id)
            ->groupBy('v.act_id')
            ->pluck('v.act_id')
            ->toArray(); //先只允许看前台上传的
        if (empty($act_id_all)) {
            return [];
        }
        $act_list = $this->select('id', 'title')->where('is_del', 1)->where('is_play', 1)->whereIn('id', $act_id_all)->orderByDesc('id')->paginate($limit)->toArray();
        if (empty($act_list['data'])) {
            return [];
        }
        $field = ['id', 'act_id', 'user_id', 'title', 'cover', 'thumb_img', 'width', 'height', 'size', 'ratio', 'browse_num', 'vote_num', 'status', 'create_time'];
        $pictureLiveWorksModel = new PictureLiveWorks();
        foreach ($act_list['data'] as $key => $val) {
            //我的活动数据
            $works_id_all = $pictureLiveVoteModel->where('user_id', $user_id)->where('act_id', $val['id'])->groupBy('works_id')->pluck('works_id')->toArray(); //先只允许看前台上传的

            //获取作品列表
            $works_list = $pictureLiveWorksModel->select($field)->whereIn('id', $works_id_all)->where('act_id', $val['id'])->whereIn('status', [1, 2, 3, 4])->where('is_del', 1)->orderByDesc('id')->limit(9)->get()->toArray();
            $count = $pictureLiveWorksModel->select($field)->whereIn('id', $works_id_all)->where('act_id', $val['id'])->whereIn('status', [1, 2, 3, 4])->where('is_del', 1)->count();
            $act_list['data'][$key]['works_list'] = $works_list;
            $act_list['data'][$key]['count'] = $count; //返回总数
        }
        return $act_list;
    }


    /**
     * 我浏览过的活动列表
     * @param user_id int 用户id
     * @param limit int 分页大小
     * @param keywords string 搜索关键词(文章标题)
     * @param start_time datetime 比赛开始时间(开始)
     * @param end_time datetime 比赛结束时间(开始)
     */
    public function myBrowseLists($user_id, $keywords = null, $start_time = null, $end_time = null, $limit = 10)
    {
        $field = ['p.id', 'p.title', 'p.img', 'p.host_handle', 'p.tel', 'p.con_start_time', 'p.con_end_time', 'p.vote_start_time', 'p.vote_end_time', 'p.address', 'p.browse_num', 'p.create_time'];
        $res = $this->from('picture_live as p')
            ->select($field)
            ->join('picture_live_browse as b', 'p.id', '=', 'b.act_id')
            ->where(function ($query) use ($keywords) {
                if ($keywords) {
                    $query->where('p.title', 'like', "%$keywords%");
                }
            })->where(function ($query) use ($start_time, $end_time) {
                if ($start_time && $end_time) {
                    $query->whereBetween('b.change_time', [$start_time, $end_time]);
                }
            })
            ->where('p.is_del', 1)
            ->where('b.user_id', $user_id)
            ->groupBy('p.id')
            ->orderByDesc('b.change_time')
            ->paginate($limit)
            ->toArray();
        $controllerObj = new Controller();
        $res = $controllerObj->disPageData($res);
        return $res;
    }

    /**
     * 判断用户是否可以上传作品
     * @param act_id 活动id
     * @param user_id 用户id
     * @param data 活动数据
     */
    public function userIsCanUploads($act_id, $user_id, $data = null)
    {
        //判断指定用户是否可以参加
        $pictureLiveBlackUserModel = new PictureLiveBlackUser();
        $black_user = $pictureLiveBlackUserModel->getBlackUser(null, $user_id); //查全部，不查某个
        if ($black_user) {
            return false; //存在就不允许参加
        }

        if (empty($data)) {
            $data = $this->detail($act_id);
        }
        //提前一个小时上传
        if ($data['con_start_time'] > date('Y-m-d H:i:s', strtotime("+1 hour"))) {
            return false;
        }
        //推迟一个小时结束上传
        if ($data['con_end_time'] < date('Y-m-d H:i:s', strtotime("-1 hour"))) {
            return false;
        }
        if ($data['uploads_way'] == 2) {
            return false;
        }
        if ($data['is_appoint'] == 2) {
            return true; //不指定就是都可以参加
        }
        //判断指定用户是否可以参加
        $pictureLiveAppointUserModel = new PictureLiveAppointUser();
        $appoint_user = $pictureLiveAppointUserModel->getAppointUser($act_id, $user_id);
        if (empty($appoint_user)) {
            return false; //不存在就不允许参加
        }
        return true;
    }

    // /**
    //  * 判断用户是否可以上传作品 包括上传数量
    //  * @param act_id 活动id
    //  * @param user_id 用户id
    //  * @param data 活动数据
    //  */
    // public function userIsCanUploadsAndNumber($act_id, $user_id, $data = null)
    // {
    //     $res = $this->userIsCanUploads($act_id, $user_id, $data);
    //     if (!$res) {
    //         return '无上传权限，不允许上传';
    //     }
    //     if ($data['uploads_number'] === 0 || $data['uploads_number'] === '0') {
    //         return true; //不限制数量，可以上传
    //     }
    //     //计算上传数量
    //     $pictureLiveWorksModel = new PictureLiveWorks();
    //     $number = $pictureLiveWorksModel->getUserWorksNumber($act_id, $user_id);
    //     if ($number >= $data['uploads_number']) {
    //         return '上传张数已达上限，' . $data['uploads_number'] . ' 张';
    //     }
    //     return true; //可以上传
    // }

    // /**
    //  * 获取用户还可以上传作品的数量
    //  * @param act_id 活动id
    //  * @param user_id 用户id
    //  * @param data 活动数据
    //  */
    // public function surplusUploadsNumber($act_id, $user_id, $data = null)
    // {
    //     $res = $this->userIsCanUploads($act_id, $user_id, $data);
    //     if (!$res) {
    //         return 0;
    //     }
    //     if ($data['uploads_number'] === 0 || $data['uploads_number'] === '0') {
    //         return 999; //不限制数量，可以上传
    //     }
    //     //计算上传数量
    //     $pictureLiveWorksModel = new PictureLiveWorks();
    //     $number = $pictureLiveWorksModel->getUserWorksNumber($act_id, $user_id);
    //     return $data['uploads_number'] - $number <= 0 ? 0 : $data['uploads_number'] - $number;
    // }

    /**
     * 判断用户是否可以上传作品 包括上传数量
     * @param act_id 活动id
     * @param user_id 用户id
     * @param data 活动数据
     */
    public function userIsCanUploadsAndNumber($act_id, $user_id, $data = null)
    {
        $res = $this->userIsCanUploads($act_id, $user_id, $data);
        if (!$res) {
            return '无上传权限，不允许上传';
        }
        // if ($data['uploads_number'] === 0 || $data['uploads_number'] === '0') {
        //     return true; //不限制数量，可以上传
        // }
        //计算上传数量
        // $pictureLiveWorksModel = new PictureLiveWorks();
        // $number = $pictureLiveWorksModel->getUserWorksNumber($act_id, $user_id);
        // if ($number >= $data['uploads_number']) {
        //     return '上传张数已达上限，' . $data['uploads_number'] . ' 张';
        // }

        //计算上传数量
        $pictureLiveWorksModel = new PictureLiveWorks();
        $total_number = $pictureLiveWorksModel->getUserWorksNumber($act_id);
        $suplus_uploads_number = 500 - $total_number; //总数不能超过500
        if ($suplus_uploads_number <= 0) {
            return '上传张数已达上限'; //已到达上传限制
        }
        $user_number = $pictureLiveWorksModel->getUserWorksNumber($act_id, $user_id);
        $user_uploads_number = $data['uploads_number'] - $user_number;

        if ($user_uploads_number <= 0) {
            return '上传张数已达上限'; //已到达上传限制
        }

        return true; //可以上传
    }

    /**
     * 获取用户还可以上传作品的数量
     * @param act_id 活动id
     * @param user_id 用户id
     * @param data 活动数据
     */
    public function surplusUploadsNumber($act_id, $user_id, $data = null)
    {
        $res = $this->userIsCanUploads($act_id, $user_id, $data);
        if (!$res) {
            return 0;
        }
        // if ($data['uploads_number'] === 0 || $data['uploads_number'] === '0') {
        //     return 999; //不限制数量，可以上传
        // }
        //计算上传数量
        $pictureLiveWorksModel = new PictureLiveWorks();
        $total_number = $pictureLiveWorksModel->getUserWorksNumber($act_id);
        $suplus_uploads_number = 500 - $total_number; //总数不能超过500
        if ($suplus_uploads_number <= 0) {
            return 0; //已到达上传限制
        }
        $user_number = $pictureLiveWorksModel->getUserWorksNumber($act_id, $user_id);
        $user_uploads_number = $data['uploads_number'] - $user_number;

        if ($user_uploads_number <= 0) {
            return 0; //已到达上传限制
        }

        return $suplus_uploads_number > $user_uploads_number ? $user_uploads_number : $suplus_uploads_number; //取小的
        // return $data['uploads_number'] - $number <= 0 ? 0 : $data['uploads_number'] - $number;
    }

    /**
     * 判断接口是否可以上传作品
     * @param act_id 活动id
     */
    public function apiIsCanUploads($act_id)
    {
        // $data = $this->detail($act_id, null, ['id', 'con_start_time', 'con_end_time', 'watermark_img', 'watermark_type', 'watermark_text']);

        $key = md5('apiIsCanUploadsDetail-' . $act_id);
        $data = Cache::get($key);
        if (!$data) {
            $data = $this->detail($act_id, null, ['id', 'con_start_time', 'con_end_time', 'watermark_img', 'watermark_type', 'watermark_text']);
            if ($data) {
                $data = $data->toArray();
                Cache::put($key, $data, 60);
            }
        }

        if (empty($data)) {
            return '直播活动不存在，不允许上传作品';
        }
        if ($data['con_start_time'] > date('Y-m-d H:i:s', strtotime("+1 hour"))) {
            return '直播活动未开始，不允许上传作品';
        }
        if ($data['con_end_time'] < date('Y-m-d H:i:s', strtotime("-1 hour"))) {
            return '直播活动已结束，不允许上传作品';
        }
        return $data;
    }


    /**
     * 获取活动状态
     * $data 活动数组
     *
     * $status 1.直播未开始  2 直播中  3 投票未开始  4 投票中  5 投票已结束  6 直播已结束
     */
    public function getPictureLiveStatus($data)
    {
        $time = date('Y-m-d H:i:s');
        if ($data['con_start_time'] > $time) {
            $status = 1;
        } else if ($data['con_start_time'] < $time && $data['con_end_time'] > $time) {
            $status = 2;
        } else if ($data['vote_start_time'] > $time && $data['con_end_time'] < $time) {
            $status = 3;
        } else if ($data['vote_start_time'] < $time && $data['vote_end_time'] > $time) {
            $status = 4;
        } else if ($data['vote_end_time'] < $time && $data['con_end_time'] > $time) {
            $status = 5;
        } else {
            $status = 6;
        }
        return $status;
    }

    /**
     * 获取活动状态（2个数据合并的状态）（特殊状态，只有当图片直播和视频直播合并时才适用）
     * $data 活动数组
     *
     * $status 直播状态  1 未开始直播 2 直播中 3 已结束
     */
    public function getPictureLiveStatusV2($data)
    {
        $time = date('Y-m-d H:i:s');
        if ($data['start_time'] > $time) {
            $status = 1;
        } else if ($data['start_time'] < $time && $data['end_time'] > $time) {
            $status = 2;
        } else {
            $status = 3;
        }
        return $status;
    }

    /**
     * 获取总浏览量
     * @param act_id 大赛id
     */
    public function getBrowseNumber($act_id)
    {
        return $this->where(function ($query) use ($act_id) {
            if ($act_id) {
                $query->where('id', $act_id);
            }
        })->where('is_del', 1)
            ->sum('browse_num');
    }
}
